//package personal.util;
//
//public interface Utilities {
////    /**
////     * 取集合交集
////     *
////     * @param l 左运算数
////     * @param r 右运算数
////     * @return 交集
////     */
////    static <T> Set<T> getIntersectionSet(final Set<T> l, final Set<T> r) {
////        Set<T> ret = new HashSet<>(l);
////        ret.retainAll(r);
////        return ret;
////    }
////
////    /**
////     * 取集合并集
////     *
////     * @param l 左运算数
////     * @param r 右运算数
////     * @return 交集
////     */
////    static <T> Set<T> getUnionSet(final Set<T> l, final Set<T> r) {
////        Set<T> ret = new HashSet<>(l);
////        ret.addAll(r);
////        return ret;
////    }
//
////    /**
////     * 计算指定自动机，指定节点集合，通过 transit 转移到的节点集合
////     *
////     * @param fa      自动机
////     * @param start   指定集合
////     * @param transit 转移
////     * @return 转移后的集合
////     */
////    static Set<Integer> moveByTransit(final ScannerFiniteAutomata fa, final Set<Integer> start, Integer transit) {
////        Set<Integer> ret = new TreeSet<>();
////        for (Integer u : start) {
////            for (Graph.Node tmp : fa.getOutEdgeAdjacencyList().get(u)) {
////                int w = tmp.w, v = tmp.v;
////                if (w == transit) ret.add(v); // u 的 transit 转移
////            }
////        }
////
////        return ret;
////    }
////
////    /**
////     * 计算指定自动机，指定节点集合，通过 transit 转移到的节点集合
////     *
////     * @param fa      自动机
////     * @param start   指定集合
////     * @param transit 转移
////     * @return 转移后的集合
////     */
////    static Set<Integer> closureByTransit(final ScannerFiniteAutomata fa, final Set<Integer> start, Integer transit) {
////        Set<Integer> ret = getUnionSet(start, moveByTransit(fa, start, transit));
////        Set<Integer> tmp = getUnionSet(ret, moveByTransit(fa, ret, transit));
////        while (!ret.equals(tmp)) {
////            ret = tmp;
////            tmp = getUnionSet(ret, moveByTransit(fa, ret, transit));
////        }
////        return ret;
////    }
//
////    /**
////     * 在 parser 自动机中，计算由单个 item 产生的闭包
////     *
////     * @param grammar 文法
////     * @param init    最初的产生式
////     */
////    static ParserFA.Node closureOfParserFANode(final Grammar grammar, final ParserFA.Item init) {
////        ParserFA.Node ret = new ParserFA.Node();
////        ret.add(init);
////        return Utilities.closureOfParserFANode(grammar, ret);
////    }
////
////        /**
////         * 在 parser 自动机中，计算由单个 item 产生的闭包
////         *
////         * @param grammar 文法
////         * @param init    最初的产生式
////         */
////        static ParserFA.Node closureOfParserFANode(final Grammar grammar, final ParserFA.Node init) {
////            ParserFA.Node ret = new ParserFA.Node();
////            ret.addAll(init);
////
////            for (int i = 0; i < ret.size(); ++i) { // 遍历 Node 中的 item
////                try {
////                    Grammar.Symbol currentSymbol = ret.get(i).getCurrentSymbol(); // 当前符号
////                    if (!(currentSymbol instanceof Grammar.NonTerminalSymbol)) continue; // 如果 item 的当前位置不是非终结符，那么 continue
////                    for (Grammar.Production production : grammar.getProductions()) { // 遍历文法中的产生式
////                        ParserFA.Item item = new ParserFA.Item(production, 0);
////                        if (ret.contains(item)) continue; // 如果产生式已在 ret 中，那么 continue
////                        if (production.leftSide() == currentSymbol) { // 如果左部是 item 的当前位置处的非终结符，
////                            ret.add(item); // 那么放入新的 item
////                        }
////                    }
////                } catch (IndexOutOfBoundsException ex) { // 当前产生式已到达末尾
////                }
////            }
////            return ret;
////        }
//
//
////        /**
////         * 在 parser 自动机中，计算由 Node 通过指定 symbol 转移到的 Node
////         *
////         * @param grammar 文法
////         * @param node    转移前的节点
////         * @param symbol  转移符号
////         * @return 转移后的节点
////         */
////        static ParserFA.Node transitBySymbol(final Grammar grammar, final ParserFA.Node node, Grammar.Symbol symbol) {
////            ParserFA.Node ret = new ParserFA.Node();
////            for (ParserFA.Item item : node) { // 遍历 Node 中的 item
////                try {
////                    Grammar.Symbol currentSymbol = item.getCurrentSymbol(); // 当前符号，如果已经到达末尾则会抛出异常
////                    if (currentSymbol != symbol) continue; // 如果 item 的当前位置不是转移符号，那么 continue
////                    ret.add(item.getNext());
////                } catch (IndexOutOfBoundsException ignored) {
////                }
////            }
////            return Utilities.closureOfParserFANode(grammar, ret);
////        }
//
//
//}
